package com.dingreading.cloud.admin.controller;

import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.admin.dto.vo.BooksV2VO;
import com.dingreading.cloud.admin.dto.vo.BooksVO;
import com.dingreading.cloud.admin.entity.Books;
import com.dingreading.cloud.admin.entity.StoreBooks;
import com.dingreading.cloud.admin.entity.Stores;
import com.dingreading.cloud.admin.service.BooksService;
import com.dingreading.cloud.admin.service.StoreBooksService;
import com.dingreading.cloud.admin.service.StoresService;
import com.dingreading.cloud.admin.util.bean.BookImportUtil;
import com.dingreading.cloud.admin.util.bean.BooksUtil;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.PageUtil;
import com.dingreading.cloud.common.util.aliyun.AliyunBookUtil;
import com.dingreading.cloud.common.util.excel.ExcelHandler;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/system/storeBooks")
@Api(tags = "总部-门店书籍管理")
public class StoreBooksController {

    @Resource
    private BooksService booksService;
    @Resource
    private StoreBooksService storeBooksService;
    @Resource
    private StoresService storesService;
    @Resource
    private BookImportUtil bookImportUtil;


    @ApiOperation(value = "分页列表")
    @PostMapping(value = "/pageList")
    public R<Object> pageList(
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "书名/书号/作者/出版社") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "启用状态 -1.下架 1.上架") @RequestParam(value = "status", required = false) Integer status
    ) {
        Stores stores = storesService.getByUid(storeUid);
        if (null == stores) return R.fail("门店获取失败");

        Page<StoreBooks> page = storeBooksService.pageList(pageUtil, stores.getId(), keyword, status, null, null, null);
        List<StoreBooks> list = page.getRecords();
        int cnt = 0;
        if (CollectionUtils.isNotEmpty(list)) {
            cnt = storeBooksService.getStoreBookCnt(stores.getId());
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total", page.getTotalRow());
        jsonObject.put("list", list);
        jsonObject.put("cnt", cnt);
        return R.ok(jsonObject);
    }

    @ApiOperation(value = "获取门店书籍详情")
    @PostMapping(value = "/getBean", produces = "application/json; charset=UTF-8")
    public R<Object> getBean(
            @ApiParam(value = "门店书籍id") @RequestParam(value = "id") Long id
    ) throws Exception {
        StoreBooks storeBooks = storeBooksService.getById(id);
        if (storeBooks == null) return R.fail("书籍获取失败");

        return R.ok(storeBooks);
    }

    @ApiOperation(value = "添加/编辑门店书籍信息")
    @PostMapping(value = "/editBooks", produces = "application/json; charset=UTF-8")
    public R<Object> editBooks(
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "分类id") @RequestParam(value = "bookLabelId", required = false) Long bookLabelId,
            @ApiParam(value = "分类") @RequestParam(value = "bookLabelName", required = false) String bookLabelName,
            @ApiParam(value = "总部书籍id") @RequestParam(value = "booksId", required = false) Long booksId,
            @ApiParam(value = "书号") @RequestParam(value = "isbn", required = false) String isbn,
            @ApiParam(value = "书名") @RequestParam(value = "bookName", required = false) String bookName,
            @ApiParam(value = "封面") @RequestParam(value = "img", required = false) String img,
            @ApiParam(value = "作者") @RequestParam(value = "author", required = false) String author,
            @ApiParam(value = "出版社") @RequestParam(value = "press", required = false) String press,
            @ApiParam(value = "出版日期") @RequestParam(value = "pubDate", required = false) String pubDate,
            @ApiParam(value = "简介") @RequestParam(value = "synopsis", required = false) String synopsis,
            @ApiParam(value = "介绍") @RequestParam(value = "introduction", required = false) String introduction,
            @ApiParam(value = "单价") @RequestParam(value = "unitPrice", required = false) Double unitPrice,
            @ApiParam(value = "库存") @RequestParam(value = "stockCount", required = false) Integer stockCount,
            @ApiParam(value = "可借数量") @RequestParam(value = "borrowCount", required = false) Integer borrowCount,
            @ApiParam(value = "状态：-1.下架 1.上架") @RequestParam(value = "status", required = false) Integer status
    ) throws Exception {
        Stores stores = storesService.getByUid(storeUid);
        if (null == stores) return R.fail("门店获取失败");

        if (stockCount == null || stockCount < 0) {
            return R.fail("请填写库存数");
        }
        if (borrowCount == null || borrowCount < 0) {
            return R.fail("请填写可借数量");
        }

        StoreBooks storeBooks = null;
        if (id == null || id <= 0) {
            // 新增，门店手动添加，不同步书籍到系统书单
            storeBooks = new StoreBooks();
            // 设置书籍来源
            if (booksId != null && booksId > 0) {
                Books books = booksService.getById(booksId);
                if (books == null) return R.fail("系统书籍获取失败");

                storeBooks.setBookNum(books.getBookNum());
                storeBooks.setSource(books.getSource());
            } else {
                storeBooks.setSource(3);
            }
            storeBooks.setStoreId(stores.getId());
        } else {
            // 修改
            storeBooks = storeBooksService.getById(id);
            if (storeBooks == null)
                return R.fail("书籍获取失败");
        }
        storeBooks.setBookLabelId(bookLabelId);
        storeBooks.setBookLabelName(bookLabelName);
        storeBooks.setBooksId(booksId);
        storeBooks.setIsbn(isbn);
        storeBooks.setBookName(bookName);
        storeBooks.setImg(img);
        storeBooks.setAuthor(author);
        storeBooks.setPress(press);
        storeBooks.setPubDate(pubDate);
        storeBooks.setSynopsis(synopsis);
        storeBooks.setIntroduction(introduction);
        storeBooks.setUnitPrice(unitPrice);
        storeBooks.setStockCount(stockCount);
        storeBooks.setBorrowCount(borrowCount);
        storeBooks.setStatus(status);
        storeBooksService.saveOrUpdate(storeBooks);

        return R.ok();
    }

    @ApiOperation(value = "删除门店书籍")
    @PostMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(@ApiParam(value = "id") @RequestParam(value = "id") Long id) {
        long l = storeBooksService.dropBean(id);
        if (l <= 0) return R.failDel();

        return R.ok();
    }

    @ApiOperation(value = "更新书籍状态")
    @PostMapping(value = "/updateStatus", produces = "application/json; charset=UTF-8")
    public R<Object> updateStatus(
            @ApiParam(value = "id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "状态：-1.下架 1.上架") @RequestParam(value = "status") Integer status
    ) {
        storeBooksService.updateStatus(id, status);
        return R.ok();
    }

    @ApiOperation(value = "导入门店书单(阿里云查询)")
    @PostMapping(value = "/importStoreBook")
    public R<Object> importStoreBook(
            @ApiParam(value = "书籍数据excel") @RequestPart(value = "books") MultipartFile multipartFile,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "阿里云查书功能 1.开启 0.禁用") @RequestParam(value = "aliYunSearch") Integer aliYunSearch
    ) throws Exception {
        Stores stores = storesService.getByUid(storeUid);
        if (stores == null) return R.fail("门店不存在");

        List<BooksVO> voList = ExcelHandler.importExcel(multipartFile, BooksVO.class, null);
        if (CollectionUtils.isEmpty(voList)) return R.fail("导入的书籍为空");

        // 获取书籍分类
        Map<String, Long> bookLabelMap = BooksUtil.getBookLabelMap();

        long storeId = stores.getId();
        int bookCount = 0;
        List<String> isbnList = new ArrayList<>();
        List<StoreBooks> newStoreBookList = new ArrayList<>();
        // 添加书籍信息
        for (int i = 0; i < voList.size(); i++) {
            BooksVO booksVO = voList.get(i);
            String bookName = booksVO.getBookName();
            if (StringUtils.isBlank(bookName)) return R.fail("填写书名,行号：" + (i + 1));
            if (bookName.length() > 255) return R.fail("书名长度超过限制,行号：" + (i + 1));
            String isbn = booksVO.getIsbn();
            if (StringUtils.isBlank(isbn)) return R.fail("填写书号,行号：" + (i + 1));
            // 出版社
            String press = booksVO.getPress();
            // 出版日期
            String pubDate = booksVO.getPubDate();
            // 作者
            String author = booksVO.getAuthor();
            // 价格
            Double price = booksVO.getPrice();
            // 数量
            Integer nums = booksVO.getNums();
            // 分类
            String bookLabel = booksVO.getBookLabel();
            // 简介
            String synopsis = booksVO.getSynopsis();

            // 创建门店书籍实体
            StoreBooks data = new StoreBooks();
            data.setStoreId(storeId);
            data.setBookName(bookName);
            data.setIsbn(isbn);
            if (StringUtils.isNotBlank(author))
                data.setAuthor(author);
            if (StringUtils.isNotBlank(press))
                data.setPress(press);
            if (StringUtils.isNotBlank(pubDate))
                data.setPubDate(AliyunBookUtil.pubDateToYmd(pubDate));
            if (null != price)
                data.setUnitPrice(price);
            if (null != nums) {
                bookCount += nums;
                data.setStockCount(nums);
                data.setBorrowCount(nums);
            } else {
                bookCount += 1;
                data.setStockCount(1);
                data.setBorrowCount(1);
            }
            if (StringUtils.isNotBlank(bookLabel)) {
                Long bookLabelId = bookLabelMap.get(bookLabel);
                if (null != bookLabelId && bookLabelId > 0) {
                    data.setBookLabelId(bookLabelId);
                    data.setBookLabelName(bookLabel);
                }
            }
            if (StringUtils.isNotBlank(synopsis)) {
                data.setSynopsis(synopsis);
            }

            isbnList.add(isbn);
            newStoreBookList.add(data);
        }

        // 异步批量添加书籍信息
        bookImportUtil.insertStoreBook(newStoreBookList, isbnList, aliYunSearch, storeId);

        return R.ok("保存书籍数量：" + bookCount + "，正在保存请稍后查询.");
    }

    @ApiOperation(value = "导入门店书单(阿里云查询)")
    @PostMapping(value = "/importStoreBookV2")
    public R<Object> importStoreBookV2(
            @ApiParam(value = "书籍数据excelV2") @RequestPart(value = "books") MultipartFile multipartFile,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "阿里云查书功能 1.开启 0.禁用") @RequestParam(value = "aliYunSearch") Integer aliYunSearch
    ) throws Exception {
        Stores stores = storesService.getByUid(storeUid);
        if (stores == null) return R.fail("门店不存在");

        List<BooksV2VO> voList = ExcelHandler.importExcel(multipartFile, BooksV2VO.class, null);
        if (CollectionUtils.isEmpty(voList)) return R.fail("导入的书籍为空");

        long storeId = stores.getId();
        List<String> isbnList = new ArrayList<>();
        List<StoreBooks> newStoreBookList = new ArrayList<>();

        Map<String, Long> bookLabelMap = BooksUtil.getBookLabelMap();
        // 添加书籍信息
        int bookCount = 0;
        for (int i = 0; i < voList.size(); i++) {
            BooksV2VO booksVO = voList.get(i);
            String bookName = booksVO.getBookName();
            if (StringUtils.isBlank(bookName)) return R.fail("填写书名,行号：" + (i + 1));
            if (bookName.length() > 255) return R.fail("书名长度超过限制,行号：" + (i + 1));
            String isbn = booksVO.getIsbn();
            if (StringUtils.isBlank(isbn)) return R.fail("填写书号,行号：" + (i + 1));
            // 数量
            Integer nums = booksVO.getNums();
            // 价格
            Double price = booksVO.getPrice();
            // 分类名称
            String bookLabelName = booksVO.getBookLabelName();

            // 创建门店书籍实体
            StoreBooks data = new StoreBooks();
            data.setStoreId(storeId);
            data.setBookName(bookName);
            data.setIsbn(isbn);
            if (null != nums) {
                data.setStockCount(nums);
                data.setBorrowCount(nums);
                bookCount += nums;
            } else {
                data.setStockCount(1);
                data.setBorrowCount(1);
                bookCount += 1;
            }
            if (null != price)
                data.setUnitPrice(price);
            if (StringUtils.isNotBlank(bookLabelName)) {
                Long bookLabelId = bookLabelMap.get(bookLabelName);
                if (bookLabelId == null)
                    return R.fail("分类未查到,行号：" + (i + 1));
                data.setBookLabelName(bookLabelName);
                data.setBookLabelId(bookLabelId);
            }

            isbnList.add(isbn);
            newStoreBookList.add(data);
        }

        // 异步批量添加书籍信息
        bookImportUtil.insertStoreBookV2(newStoreBookList, isbnList, aliYunSearch, storeId);

        return R.ok("保存书籍数量：" + bookCount + "，正在保存请稍后查询.");
    }

    @ApiOperation(value = "门店书籍补充数量")
    @PostMapping(value = "/updateStockNum", produces = "application/json; charset=UTF-8")
    public R<Object> updateStockNum(
            @ApiParam(value = "书籍数据excelV2") @RequestPart(value = "books") MultipartFile multipartFile,
            @ApiParam(value = "门店id") @RequestParam(value = "id") Long id
    ) {
        Stores stores = storesService.getById(id);
        if (stores == null) return R.fail("门店不存在");

        List<StoreBooks> storeBooksList = storeBooksService.getNoLabelName(stores.getId());
        if (CollectionUtils.isNotEmpty(storeBooksList)) {
            List<String> isbns = storeBooksList.stream().map(StoreBooks::getIsbn).distinct().collect(Collectors.toList());

            List<Books> booksList = booksService.getByIsbnAndLabelNotNull(isbns);

            Map<String, List<Books>> bookMap = null;
            if (CollectionUtils.isNotEmpty(booksList)) {
                bookMap = booksList.stream().collect(Collectors.groupingBy(Books::getIsbn));
            }
            if (null != bookMap) {
                for (StoreBooks storeBooks : storeBooksList) {
                    String isbn = storeBooks.getIsbn();
                    List<Books> booksList2 = bookMap.get(isbn);
                    if (CollectionUtils.isNotEmpty(booksList2)) {
                        Books books = booksList2.get(0);

                        // 更新分类
                        storeBooksService.updateLabelId(stores.getId(), isbn, books.getBookLabelId(), books.getBookLabelName());
                    }
                }
            }
        }
        return R.ok();
    }

    @ApiOperation(value = "门店书籍补充分类")
    @PostMapping(value = "/updateBookLabel", produces = "application/json; charset=UTF-8")
    public R<Object> updateBookLabel(
            @ApiParam(value = "门店id") @RequestParam(value = "id") Long id
    ) {
        Stores stores = storesService.getById(id);
        if (stores == null) return R.fail("门店不存在");

        List<StoreBooks> storeBooksList = storeBooksService.getNoLabelName(stores.getId());
        if (CollectionUtils.isNotEmpty(storeBooksList)) {
            List<String> isbns = storeBooksList.stream().map(StoreBooks::getIsbn).distinct().collect(Collectors.toList());

            List<Books> booksList = booksService.getByIsbnAndLabelNotNull(isbns);

            Map<String, List<Books>> bookMap = null;
            if (CollectionUtils.isNotEmpty(booksList)) {
                bookMap = booksList.stream().collect(Collectors.groupingBy(Books::getIsbn));
            }
            if (null != bookMap) {
                for (StoreBooks storeBooks : storeBooksList) {
                    String isbn = storeBooks.getIsbn();
                    List<Books> booksList2 = bookMap.get(isbn);
                    if (CollectionUtils.isNotEmpty(booksList2)) {
                        Books books = booksList2.get(0);

                        // 更新分类
                        storeBooksService.updateLabelId(stores.getId(), isbn, books.getBookLabelId(), books.getBookLabelName());
                    }
                }
            }
        }
        return R.ok();
    }

}
